package com.chinaisafe.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chinaisafe.base.common.dto.auth.AuthUser;
import com.chinaisafe.gateway.client.auth.UaaAuthHelper;
import com.chinaisafe.user.entity.SysTenant;
import com.chinaisafe.user.mapper.SysTenantMapper;
import com.chinaisafe.user.service.SysTenantService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaisafe.user.vo.request.SysTenantReqVO;
import com.chinaisafe.user.vo.request.TenantChangeStatusReqVO;
import com.chinaisafe.user.vo.response.LoginTenantTreeVO;
import com.chinaisafe.user.vo.response.LoginTenantVO;
import com.chinaisafe.user.vo.response.SysTenantRespVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.chinaisafe.base.common.exception.BizException;
import com.chinaisafe.base.mybatisplus.constant.MybatisplusConstants;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinaisafe.base.mybatisplus.util.MpQueryWrapperPageUtil;

import java.util.*;
import java.util.stream.Collectors;

/**
 * SysTenantServiceImpl
 * Description：租户服务实现类
 *
 * @author xuefu.shu
 * @date 2024-07-12 10:22:08
 */
@Slf4j
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService {

    @Override
    public IPage<SysTenantRespVO> getPageList(SysTenantReqVO sysTenantReqVO) {
        // 分页设置
        Page<SysTenant> page = MpQueryWrapperPageUtil.buildWrapperPage(new Page<>(), sysTenantReqVO);

        // 查询条件构造
        QueryWrapper<SysTenant> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysTenant::getDeleted, MybatisplusConstants.LOGIC_NOT_DELETE_VALUE)
                .eq(Objects.nonNull(sysTenantReqVO.getEnable()), SysTenant::getEnable, sysTenantReqVO.getEnable())
                .like(Objects.nonNull(sysTenantReqVO.getName()), SysTenant::getName, sysTenantReqVO.getName());
        return baseMapper.getPageList(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysTenantRespVO add(SysTenantReqVO sysTenantReqVO) {
        // 新增和编辑逻辑相同的情况下 直接调用新增或编辑方法
        return this.addOrUpdate(sysTenantReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysTenantRespVO update(SysTenantReqVO sysTenantReqVO) {
        // 新增和编辑逻辑相同的情况下 直接调用新增或编辑方法
        return this.addOrUpdate(sysTenantReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysTenantRespVO addOrUpdate(SysTenantReqVO sysTenantReqVO) {
        Long sysTenantId = sysTenantReqVO.getId();
        if (sysTenantId != null){
            // 编辑
            SysTenant sysTenant = baseMapper.selectById(sysTenantId);
            Optional.ofNullable(sysTenant).orElseThrow(() -> BizException.build("未找到要修改的租户信息"));
        }
        SysTenant sysTenant2Save = sysTenantReqVO.convertToEntity();
        boolean success = this.saveOrUpdate(sysTenant2Save);
        if (success) {
            return SysTenantRespVO.convertFromEntity(sysTenant2Save);
        } else {
            BizException.throwException("操作失败，请刷新后重试");
        }
        return null;
    }

    @Override
    public SysTenantRespVO getDetailById(Long sysTenantId) {
        SysTenant sysTenant = baseMapper.selectById(sysTenantId);
        Optional.ofNullable(sysTenant).orElseThrow(() -> BizException.build("未找到对应租户信息"));
        return SysTenantRespVO.convertFromEntity(sysTenant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(Long[] sysTenantIds) {
        if (sysTenantIds.length > 0) {
            this.removeByIds(Arrays.asList(sysTenantIds));
        }
    }


    @Override
    public LoginTenantVO tenantUserTree() {
        AuthUser user = UaaAuthHelper.getUser();


        LoginTenantVO loginTenantVo = new LoginTenantVO();

        Set<SysTenant> tenantIds = baseMapper.findIdByAccountId(user.getAccountId());

        if (CollectionUtil.isNotEmpty(tenantIds)) {
            List<LoginTenantTreeVO> result = new ArrayList<>();
            Set<Long> ids = tenantIds.stream().map(SysTenant::getId).collect(Collectors.toSet());
            Set<Long> topIds = baseMapper.findTopIdByIdIn(ids);

            List<LoginTenantTreeVO> tenantTreeVos = baseMapper.findByTopIdIn(topIds);

            loginTenantVo.setTenantCodes(tenantIds.stream().map(SysTenant::getCode).collect(Collectors.toSet()));

            List<LoginTenantTreeVO> useTenantIds = new ArrayList<>();
            Map<Long, LoginTenantTreeVO> tenantTreeVoMap = tenantTreeVos.stream()
                                            .map(item->{
                                                item.setCheckable(false);
                                                if (Objects.isNull(item.getParentId()) || item.getParentId() == 0L) {
                                                    result.add(item);
                                                }
                                                if (ids.contains(item.getId())) {
                                                    useTenantIds.add(item);
                                                    item.setCheckable(true);
                                                }
                                                return item;
                                            })
                                            .collect(Collectors.toMap(LoginTenantTreeVO::getId, v -> v, (v1, v2) -> v1));

            useTenantIds.stream().forEach(item->{
                boolean next = true;
                LoginTenantTreeVO thisItem = tenantTreeVoMap.get(item.getId());
                while (next) {
                    if (Objects.nonNull(thisItem.getParentId()) && tenantTreeVoMap.containsKey(thisItem.getParentId())) {
                        LoginTenantTreeVO tenantTreeVO = tenantTreeVoMap.get(thisItem.getParentId());
                        next = tenantTreeVO.setChildrenBy(thisItem);
                        if (next) {
                            thisItem = tenantTreeVoMap.get(thisItem.getParentId());
                        }
                    } else {
                        next = false;
                    }
                }
            });
            loginTenantVo.setTreeVo(result);
        }

        return loginTenantVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(TenantChangeStatusReqVO changeStatusReqVO) {
        int update = baseMapper.update(null, new UpdateWrapper<SysTenant>().lambda().eq(SysTenant::getId, changeStatusReqVO.getTenantId()).set(SysTenant::getEnable, changeStatusReqVO.getEnable()));
        log.info("租户状态修改成功，影响行数：{}", update);
    }


}
